home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / grafik / converter / limbo4.0 / src / 2d / bitio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-16  |  7.1 KB  |  203 lines

  1. #include "includes.h"
  2.  
  3. /**************************************|****************************************
  4.  "Routine   : PutBit"
  5.                                                           MSB    LSB
  6.                                                     b[1]   | b[0] |
  7. Input  par: int bitn (bit number to be placed ie: 10100101 00110101   )
  8.                                                   ^               ^
  9.                                                 bit n           bit 0 
  10.  
  11.             unsigned char bit    (bit to be placed 0 or 1)
  12.             unsigned char *bytes (byte array to be manipulated)
  13. Output par: unsigned char (manipulated byte extracted from bytes[])
  14. Function  : put a bit in a bytearray at place bitn
  15. ***************************************|***************************************/
  16.  
  17.  unsigned char PutBit(int bitn, unsigned char bit, unsigned char *bytes)
  18.   {
  19.    int index  = bitn / 8;
  20.    int b=bitn-index*8;
  21.    unsigned char in,out;
  22.    
  23.    /* if (index >= strlen(bytes) ) 
  24.    ErrorHandler(OUT_OF_RANGE,"PutBit needs larger array to place bitn"); */
  25.    
  26.    in = ~(0x00 | (1 << b)) ; /* setup mask */
  27.    out = bytes[index] & in;  /* reset bitn */
  28.    out = out          | (bit << b); /* set bitn to 0 or 1 */
  29.    
  30.    return out;
  31.   }
  32.  
  33. /**************************************|****************************************
  34.  "Routine   : GetBit"
  35.                                                       MSB    LSB
  36.                                                 b[1]   | b[0] |
  37. Input  par: int bitn (bit to be extracted ie: 10100101 00110101
  38.                                               ^               ^
  39.                                             bit n           bit 0
  40.             unsigned char *bytes (byte array to extract from)
  41. Output par: unsigned char (bit extracted)
  42. Function  : extract a specific bit from a bytearray
  43. ***************************************|***************************************/
  44.  
  45.  unsigned char GetBit(int bitn, unsigned char *bytes)
  46.   {
  47.    int index  = bitn / 8;
  48.    int b=bitn-index*8;
  49.    /* if (index >= strlen(bytes) ) 
  50.    ErrorHandler(OUT_OF_RANGE,"GetBit needs larger array to extract bitn"); */
  51.    return (unsigned char) ((bytes[index] >> b) & 1);
  52.   }
  53.  
  54. /**************************************|****************************************
  55.  "Routine   : IOBitArray"
  56. Input  par: int mode   (mode for routine i.e. FILE_READ, FILE_WRITE,
  57.                         FILE_APPEND or FILE_CLOSE )
  58.             char *file (sting for filename to be treated)
  59.             unsigned char *bitarray (in or output bitarray -> warning:
  60.                 bitarray is altered in readmode as global var)
  61. Output par: int (error)
  62. Function  : General module for reading and writeing a specfic numbers of bits.
  63.             Bits is buffered through a byte - therefore explicit open, read, write,
  64.             append and close actions are needed.
  65.  
  66.             Works as a finite state maschine being in read, write or append mode:
  67.  
  68.             FSM:                            FILE_READ
  69.                                            /----<----\
  70.                         FILE_OPENREAD      |         |
  71.             FILE_CLOSED-------->------FILE_OPENREAD--/ 
  72.             | |  | |  ^                       |
  73.             | |  | |  \--------<--------------/
  74.             | |  | |       FILE_CLOSE
  75.             | |  ^ |                        FILE_WRITE
  76.             | |  | |                       /----<----\
  77.             | |  | |    FILE_OPENWRITE     |         |
  78.             | |  | \----------->------FILE_OPENWRITE-/
  79.             ^ |  |                            |
  80.             | |  \-------------<--------------|
  81.             | |            FILE_CLOSE
  82.             | |                             FILE_WRITE
  83.             | |                            /----<----\
  84.             | |        FILE_OPENAPPEND     |         |
  85.             | \---------------->------FILE_OPENAPPEND/
  86.             |                                 |
  87.             \------------------<--------------/
  88.                            FILE_CLOSE
  89.  
  90. ***************************************|***************************************/
  91.  
  92.  int IOBitArray(int mode, char *file,int nbits, unsigned char *bitarray)
  93.   {
  94.    static int internalmode=FILE_CLOSED;
  95.    static FILE *iofile;
  96.    static unsigned char buff=0;
  97.    static int buffn=0;
  98.    
  99.    unsigned char temp;
  100.    int i,j=0,duum; /* j=bit nr in bitarray */
  101.    
  102.    if ((mode==FILE_WRITE) || (mode==FILE_APPEND)) /* write/append bits */
  103.     {
  104.      if ((internalmode==FILE_OPENWRITE) ||  (internalmode==FILE_OPENAPPEND))
  105.       {
  106.        while (j<nbits)
  107.         {
  108.          if (buffn<8)  buff = buff | (GetBit(j++,bitarray) << buffn++);
  109.          /* fill up byte buffer */
  110.          else
  111.           {
  112.            if (0>fprintf(iofile,"%c",buff))
  113.            ErrorHandler(ERROR_WRITING,"IOBitArray could not write bits"); 
  114.            buff=0;  /* reset buffer */
  115.            buffn=0; /* reset buff counter */
  116.           }
  117.         }
  118.        return(NO_ERROR);
  119.       }
  120.      else return(FILEMODE_ERROR);
  121.     }
  122.    
  123.    if (mode==FILE_READ) /* read bits */
  124.     {
  125.      if (internalmode==FILE_OPENREAD)
  126.       {
  127.        i=0;
  128.        
  129.        do bitarray[i]=0;
  130.        while(i++<(nbits/8)+2); /* reset array */
  131.        
  132.        while (j<nbits)
  133.         {
  134.          if (buffn==0)
  135.           {
  136.            duum=fgetc(iofile);
  137.            buff=(unsigned char)duum;
  138.            if (duum==EOF) ErrorHandler(ERROR_READING,"Reached EOF");
  139.            buffn=8; /* 8 bit in buffer now */
  140.           }
  141.          temp = (GetBit(8-buffn--,&buff));
  142.          bitarray[j/8] = PutBit(j,temp,bitarray);
  143.          j++;
  144.         }
  145.        return(NO_ERROR);
  146.       }
  147.      else return(FILEMODE_ERROR);
  148.     }
  149.    
  150.    else if ((mode==FILE_OPENWRITE) || (mode==FILE_OPENAPPEND) || (mode==FILE_OPENREAD) )
  151.    /* should we go to writemode ? */
  152.     {
  153.      if (internalmode==FILE_CLOSED)
  154.       {
  155.        if (mode==FILE_OPENWRITE) 
  156.         {
  157.          if ((iofile=fopen(file,"wb")) == NULL) return(UNABLE_TO_OPEN);
  158.          internalmode=FILE_OPENWRITE; /* really in writemode now */
  159.         }
  160.        else if (mode == FILE_OPENAPPEND)
  161.         {
  162.          if ((iofile=fopen(file,"ab")) == NULL) return(UNABLE_TO_OPEN);
  163.          internalmode=FILE_OPENAPPEND; /* really in appendmode now */
  164.         }
  165.        else
  166.         {
  167.          if ((iofile=fopen(file,"rb")) == NULL) return(UNABLE_TO_OPEN);
  168.          internalmode=FILE_OPENREAD; /* really in readmode now */
  169.         }
  170.        return(NO_ERROR);
  171.       }
  172.      else return(FILEMODE_ERROR);
  173.     }
  174.    
  175.    else if (mode==FILE_CLOSE) /* close file ? */
  176.     {
  177.      if ((internalmode==FILE_OPENWRITE) || (internalmode==FILE_OPENAPPEND))
  178.       {
  179.        if (buffn!=0)
  180.         {
  181.          if (0>fprintf(iofile,"%c",buff)) 
  182.          ErrorHandler(ERROR_WRITING,"IOBitArray could not write bits");
  183.          buff=0;
  184.          buffn=0;
  185.         }
  186.        if (fclose(iofile)) return(UNABLE_TO_CLOSE);
  187.        internalmode=FILE_CLOSED; /* in no mode now */
  188.        return(NO_ERROR);
  189.       }
  190.      else if (internalmode==FILE_READ)
  191.       {
  192.        if (fclose(iofile)) return(UNABLE_TO_CLOSE);
  193.        internalmode=FILE_CLOSED; /* in no mode now */
  194.        buff=0;
  195.        buffn=0;
  196.        return(NO_ERROR);
  197.       }
  198.      else return(FILEMODE_ERROR);
  199.     }
  200.    
  201.    else return(FILEMODE_ERROR);
  202.   }
  203.